//
// Created by User on 24-10-7.
//

#ifndef GENERAL_ENCODER_H
#define GENERAL_ENCODER_H

#include "encoder_error.hpp"
#include "media_packet.h"

#include <queue>


extern "C" {
struct AVCodec;
struct AVPacket;
struct AVCodecContext;
struct AVRational;
struct AVCodecParameters;
}

namespace interfaces
{
    class frame_provider;
}

namespace utils
{
    class video_config;
    class audio_config;
}

namespace encoder
{
    class general_encoder
    {
    public:
        general_encoder(const utils::video_config& config, interfaces::frame_provider& provider);

        general_encoder(const utils::audio_config& config, interfaces::frame_provider& provider);

        utils::media_packet get_packet();

        const AVCodecParameters* get_code_parameters() const;

        AVRational get_timebase() const;

        int total_frame() const;

        virtual ~general_encoder();

    protected:
        virtual const AVCodec* get_video_encoder(const utils::video_config& config);

        virtual const AVCodec* get_audio_encoder(const utils::audio_config& config);

    private:
        void init_video_encoder(const utils::video_config& config);

        void init_audio_encoder(const utils::audio_config& config);

        void clean_encoder(error::encoder_error::type _type);

        void encode_packet();

    private:
        interfaces::frame_provider& m_provider;
        const AVCodec* m_codec{};
        AVCodecContext* m_code_ctx{};
        mutable AVCodecParameters* m_code_par{};
        std::queue<utils::media_packet> m_que;
        AVPacket* m_pkt{};
        bool is_end{false};
    };
}


#endif //GENERAL_ENCODER_H
